import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;

public class DataFileStorer implements Runnable{
	
	private HashMap<Integer, Integer> stations;
	private int stationsAmount;
	
	
	private RandomAccessFile file;
	
	private String currentDate;
	private String currentHour;
	private String currentMinute;
	
	private Queue<Data> buffer;
	
	private static int DATA_LENGTH = 56;
	private int counter = 0;
	private int measurementAmount = 0;

	
	public DataFileStorer(HashMap<Integer, Integer> stations){
		
		this.stations = stations;		
		this.stationsAmount = stations.size();
		this.buffer = new LinkedList<Data>();
		resetDateTime();		
		createFile();
		
		new Thread(this).start();
	}
	
	/**
	 * Creates the file and if the needed directory does not exists it will also make the directory
	 */
	public void createFile(){
		try {
			file = new RandomAccessFile(new File("Measurements\\" + currentDate + "\\" + currentHour + ".txt"), "rw");
			//file = new RandomAccessFile(new File("Measurements\\" + currentDate + "\\" + currentHour+ ".txt"), "rw");
			System.out.println("File "+currentMinute+" is aangemaakt");
		} catch (FileNotFoundException e) {
			if(!new File("Measurements").exists()){
				new File("Measurements").mkdir();
				System.out.println("Map measurements is aangemaakt");
			} else{ 
			//else if(!new File("Measurements\\" + currentDate).exists()){
				new File("Measurements\\" + currentDate).mkdir();
				System.out.println("Map "+currentDate+" is aangemaakt");
			} 
//			else{
//				new File("Measurements\\" + currentDate + "\\" + currentHour).mkdir();
//				System.out.println("Map "+currentHour+" is aangemaakt");
//			}			
			createFile();
		}		
	}
	
	/**
	 * Returns the current date
	 * @return date The current date
	 */
	public String getCurrentDate(){
		SimpleDateFormat dateFormat = new SimpleDateFormat("ddMMyyyy");
		return dateFormat.format(new Date(System.currentTimeMillis()));		
	}
	
	/**
	 * Returns current hour
	 * @return Hour current hour
	 */
	public String getCurrentHour(){
		SimpleDateFormat hourFormat = new SimpleDateFormat("k");
		return hourFormat.format(new Date(System.currentTimeMillis()));
	}
	
	/**
	 * Adds the data to the buffer 
	 * @param data Data object which holds the data
	 */
	public synchronized void addToBuffer(Data data){		
		buffer.add(data);		
	}
	
	/**
	 * Adds a HashMap of data to the buffer
	 * @param d HashMap with all the data objects
	 */
	public synchronized void addAllToBuffer(HashMap<Integer, Data> d) {
		buffer.addAll(d.values());
	}
	
	/**
	 * Takes data object from buffer
	 * @return data Data object which holds the data
	 */
	public synchronized Data removeFromBuffer(){
		return buffer.poll();
	}	
	
	/**
	 * Resets the time and the date saved in the variables currentDate and currentHour
	 */
	public void resetDateTime(){
		currentDate = getCurrentDate();
		currentHour = getCurrentHour();		
	}
	
	@Override
	public void run() {			

		Boolean empty = null;
		System.out.println("FileStorer started");
		System.out.println("Waiting for full buffer");	
		System.out.println("Er zijn genoeg objecten");
		
		
		int index = 0;
		while(true){
//			This line can be used to save the data per Interval
//			if(Math.floor(Double.parseDouble(getCurrentHour())%INTERVAL)==0 && !currentMinute.equals(getCurrentMinute()) && counter == stationsAmount){			
			if(currentHour != getCurrentHour() && !currentHour.equals(getCurrentHour())){				
				try {
					file.close();
					file = null;
					System.out.println("Nieuwe file wordt gemaakt......");
				} catch (IOException e) {					
					e.printStackTrace();
				}
				resetDateTime();							
				createFile();
				counter = 0;
				measurementAmount = 0;
			} else if(counter == stationsAmount){
				counter = 0;
				measurementAmount++;							
			}	
			try {				
				empty = buffer.isEmpty();				
				if(!empty){	
					synchronized(this){
						Data data = removeFromBuffer();
						index = stations.get(data.getStn());
						file.seek((measurementAmount*(DATA_LENGTH*stationsAmount))+(DATA_LENGTH*index));
						String datas = data.getAllData();
						if(datas.trim().equals("")){
							System.out.println("Empty string written");
						}
						file.writeBytes(datas);						
						counter++;						
					}											
				}				
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			empty = null;
		}
	}
}